iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
Software Development

Rails 開發,每日一套件介紹! 系列 第 17

Day 17: 淺談隱藏在 Rails 中的美洲獅 - PUMA

  • 分享至 

  • xImage
  •  

Hello, 我是 Weber,一位工程師,斜槓鼓手與行銷顧問。
今天是每日一套件的第 17 天,繼續跟著我一起認識 Rails 開發好用的 30 個套件,建立出自己的常用套件庫吧!

Day 17: PUMA

今天要講一個隱藏在 Rails 之內的套件,尤其是我這種一入手就是從 Rails 7 開始的資淺工程師,PUMA 其實已經是一個內建的套件,我是一路一直到專案的後期,開始進行部署的時候,才開始注意到這個套件的存在。

進入開發者的領域後,真的是覺得學無止盡。學習 Ruby On Rails 後,現在開始逐步去研究她的運行機制,裡面真是滿滿的大秘寶,各種待讀清單已經塞爆我的書籤,真的是很有念研究所的感覺,哈哈哈。

回歸正題:
PUMA 是一個支援 Rails / Rack 的伺服器系統,是開源且免費的,License 是 BSD 3-Clause

在 Rails 5.0 後,為了因應支援 Websocket,而加入了 ActionCable 的機制。PUMA 則成為 Rails 官方預設的 HTTP Server。再此之前,還有 Unicorn、WEBrick、Passenger等。這段歷史,花了我很多時間閱讀,各位有興趣的話,也可以去讀一點。

PUMA 有什麼樣的特色優點呢?

  • 多線程 (Multi-threaded):
    PUMA 被設計成高性能的伺服器,可以處理大量的同時連接和請求。它使用 Multi-threaded,每個請求都是獨立的 thread,有助於減少記憶體的使用量以及每秒可以處理更多的請求。

  • 多進程 (Multi-process):
    PUMA 在 Clustered Mode (Multi-Workers) 時會採用 Pre-fork 的方式來處理,也就是在啟動時,就預先產生一些子進程(Process),接著等待請求進來,以減少頻繁創造和銷毀 Process 的開銷。而每個 Process 使用寫入時複製(copy-on-write, 簡稱 COW)來減少了記憶體的占用。

  • 可獨立運行(Standalone):
    可獨立運行並支援 SSL,號稱 Zero-downtime 及 Rolling restarts,以及可以在不需要Reverse proxy 的情況下部署。

  • 輕量:
    Puma 的佔用系統資源相對較少,適合部署的輕量級伺服器選項之一。

  • 與 Rails 整合完善:
    這點也相當重要,與 Rails 高度整合,可以輕鬆的設定跟執行。

講了一大堆,很抱歉用了一堆"晶晶體"。
我其實也是個講話很常 "晶晶體" 的人,不過有時候,真的有些字詞就是用英文表達最好理解,只能意會不能言傳,轉成中文,有時候詞不達意 或者 描述不清。
沒辦法,網路科技母語原生於英文,只能盡力表達了。(相信讀過原文書研究的人都能懂)

其實這樣的問題不只是在英翻中,中翻英或者在任何翻譯都有類似的問題。有些中文字詞,可能兩個字就能表達意涵,翻譯成英文,就會變成一長段不知所謂的句子。

安裝與使用:

對於 Rails 5.0 之後的使用者,其實你不需要再安裝了,rails new 出來後,已經內建在 Gemfiles 裡,可以直接跳過安裝。
至於 Rails 5.0 以下的朋友...誒~我可能幫不了你,Rails 4 跟 5 中間有個很大的門檻,我目前功力不到,雖然讀PUMA官方文件安裝應該是很簡單,但會不會有延伸的問題,這我不知道...只能建議多發問!

幾個重要設定,這邊提一下設定的指令。

$ puma -t 16:16 -w 2 --preload

翻譯一下上面的指令就是:

Thread Pool:

(執行緒池???你看~很難翻譯吧,這什麼東西)
-t 是代表 --threads 的意思,後面的數字是 minimum 跟 maximum。預設是 0:16 在 MRI 是 0:5。

Clustered Mode:

-w 是代表 --workers,這就是在前面提到的 Clustered Mode (Multi-Workers)。

Preload (預先載入):

--preload 懶得翻譯了,自己看。

In clustered mode, Puma can "preload" your application. This loads all the application code prior to forking. Preloading reduces total memory usage of your application via an operating system feature called copy-on-write.

或者 你可以透過在 puma.rb 的檔案中 寫入 preload_app!

用理解的方式,翻譯上面的指令就是:

$ puma -t 16:16 -w 2 --preload

總共會產生 32 個 threads,每一個 Worker process 分別各有 16 個。並且預先載入。

綁定 TCP / Sockets:

綁定 socket 的指令用 -b 代表 --bind,範例如下:

$ puma -b tcp://127.0.0.1:9292

如果是用 UNIX Socket:

$ puma -b unix:///var/run/puma.sock

SSL sockets:

$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'

設定 configuration file:

$ puma -C /path/to/config

通常 puma.rb 都是在 config 資料夾下,如果有另外的前綴資料夾,可以透過這個指令設定。
另外這個指令在部署時 Procfile,也會使用到,範例:

web: bundle exec puma -C config/puma.rb

另外提供我自己專案中的 puma 設定來參考,寫的很生疏,如果有更好的寫法,也很樂於接受建議,謝謝各位。

# frozen_string_literal: true

max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 5)
min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
threads min_threads_count, max_threads_count

preload_app!

worker_timeout 3600 if ENV.fetch('RAILS_ENV', 'development') == 'development'
rackup      DefaultRackup if defined?(DefaultRackup)
port ENV.fetch('PORT', 3000)
environment ENV.fetch('RAILS_ENV', 'development')

pidfile ENV.fetch('PIDFILE', 'tmp/pids/server.pid')

plugin :tmp_restart

真的寫太多字了,我們明天見!


上一篇
Day 16: 背景作業的強力側踢 - Sidekiq (上)
下一篇
Day 18: 集會員系統之大成 - Devise
系列文
Rails 開發,每日一套件介紹! 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言